package cn.anecansaitin.whimsy.common.entity;

import cn.anecansaitin.whimsy.common.register.ModEntities;
import cn.anecansaitin.whimsy.common.register.ModItems;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;

import javax.annotation.Nullable;
import java.util.UUID;

public class PhantasmArrow extends AbstractArrow {
    private static final EntityDataAccessor<Integer> DATA_ENEMY_ID = SynchedEntityData.defineId(PhantasmArrow.class, EntityDataSerializers.INT);
    @Nullable
    private UUID enemyId;
    @Nullable
    private Entity enemy;
    private static final ItemStack defaultItem = ModItems.PHANTASM_ARROW_ITEM.get().getDefaultInstance();

    public PhantasmArrow(EntityType<? extends AbstractArrow> entityType, Level level) {
        super(entityType, level, defaultItem);
        pickup = Pickup.CREATIVE_ONLY;
    }

    //通过弓箭直接射出
    public PhantasmArrow(LivingEntity shooter) {
        super(ModEntities.PHANTASM_ARROW.get(), shooter, shooter.level(), defaultItem);
        addTag("bow_shot");
    }

    //通过附魔额外制造
    public PhantasmArrow(LivingEntity shooter, Entity enemy) {
        super(ModEntities.PHANTASM_ARROW.get(), shooter, shooter.level(), defaultItem);
        pickup = Pickup.CREATIVE_ONLY;
        this.enemy = enemy;
        enemyId = enemy.getUUID();

        if (!level().isClientSide) {
            setEnemyId(enemy.getId());
        }
//        setNoGravity(true);
//        setNoPhysics(true);
    }

    @Override
    public void tick() {
        if (enemy == null) {
            if (level().isClientSide) {
                if (getEnemyId() != -1) {
                    enemy = level().getEntity(getEnemyId());
                }
            } else {
                if (enemyId != null) {
                    enemy = ((ServerLevel) level()).getEntity(enemyId);

                    if (enemy != null) {
                        setEnemyId(enemy.getId());
                    }
                }
            }
        }

        if (enemy == null || !enemy.isAlive()) {
            super.tick();
            return;
        }

        double speed = 3f;
        if (enemy.getParts() != null) {
            setDeltaMovement(enemy.getParts()[0].getEyePosition().subtract(position()).normalize().multiply(speed, speed, speed));
        } else {
            setDeltaMovement(enemy.getEyePosition().subtract(position()).normalize().multiply(speed, speed, speed));
        }

        super.tick();
    }

    @Override
    protected void onHitEntity(EntityHitResult result) {
        Entity enemy = result.getEntity();

        if (enemy.invulnerableTime > 10) {
            enemy.invulnerableTime = 9;
        }

        super.onHitEntity(result);

        discard();
    }

    @Override
    public void setCritArrow(boolean pCritArrow) {
        //因为暴击粒子太遮挡视野了，所以我把它取消了
    }

    @Override
    public void shoot(double pX, double pY, double pZ, float pVelocity, float pInaccuracy) {
        //让这只箭的速度更快，但是快了会导致客户端现实的位置不正常，但实际上是正常的
        pVelocity *= 1.5f;
        super.shoot(pX, pY, pZ, pVelocity, pInaccuracy);
    }

    @Override
    protected ItemStack getPickupItem() {
        if (enemy == null) {
            return new ItemStack(ModItems.PHANTASM_ARROW_ITEM.get());
        } else {
            return ItemStack.EMPTY;
        }
    }

    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        getEntityData().define(DATA_ENEMY_ID, -1);
    }

    @Override
    public void readAdditionalSaveData(CompoundTag compound) {
        super.readAdditionalSaveData(compound);

        if (compound.contains("enemy")) {
            enemyId = compound.getUUID("enemy");
        }
    }

    @Override
    public void addAdditionalSaveData(CompoundTag compound) {
        super.addAdditionalSaveData(compound);

        if (enemyId != null) {
            compound.putUUID("enemy", enemyId);
        }
    }

    public void setEnemyId(int id) {
        getEntityData().set(DATA_ENEMY_ID, id);
    }

    public int getEnemyId() {
        return getEntityData().get(DATA_ENEMY_ID);
    }
}
